package org.lightcommons.ioc.guice;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;

import org.aopalliance.intercept.MethodInterceptor;

import com.google.inject.Binder;
import com.google.inject.cglib.proxy.Proxy;
import com.google.inject.matcher.Matcher;

/**
 * Utility class for GUICE
 * @author GL
 *
 */
public class GuiceUtils {

	/**
	 * bind Interceptors ,it can also bind to Interface and AbstractClasses,it means ,you could write code only in interceptors.
	 * @param binder
	 * @param dynamicClasses interfaces and abstract classes
	 * @param typeMatcher
	 * @param methodMatcher
	 * @param interceptors
	 */
	public static void bindInterceptor(Binder binder,Collection<Class<?>> dynamicClasses,Matcher<? super Class<?>> typeMatcher,Matcher<? super Method> methodMatcher,MethodInterceptor... interceptors){
		binder.bindInterceptor(typeMatcher, methodMatcher, interceptors);
		if(dynamicClasses==null)
			return;
		for(Class cls : dynamicClasses){
			if(typeMatcher.matches(cls)){
				if(cls.isInterface()){
					binder.bind(cls).toInstance(Proxy.newProxyInstance(cls.getClassLoader(),
	                        new Class<?>[] { cls }, new AopAllianceJdkProxyAdapter(typeMatcher,methodMatcher,interceptors)));
				}else if(Modifier.isAbstract(cls.getModifiers())){
					binder.bind(cls).toInstance(com.google.inject.cglib.proxy.Enhancer.create(cls,
	                        new AopAllianceCglibAdapter(typeMatcher,methodMatcher,interceptors)));
				}
			}
		}
	}
	
}
